package com.ruoyi.service.impl;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ruoyi.utils.WeChatPayUtil;
import com.ruoyi.utils.config.WeChatConfig;
import org.springframework.stereotype.Service;

@Service
public class WeChatPayService {

    // 生成预支付交易单
    public Map<String, String> createOrder(String orderId, String totalFee, String openid, String body) {
        System.out.println(111);
        Map<String, String> params = new HashMap<>();
        params.put("appid", WeChatConfig.APP_ID);
        System.out.println("appid:" + WeChatConfig.APP_ID);
        params.put("mch_id", WeChatConfig.MCH_ID);
        System.out.println("mch_id:" + WeChatConfig.MCH_ID);
        String nonceStr = WeChatPayUtil.generateNonceStr();
        params.put("nonce_str", nonceStr);
        System.out.println("nonce_str:" + nonceStr);
        params.put("body", body);//商品描述，支付结果用户微信收到的描述
        System.out.println("body:" + body);
        params.put("out_trade_no", orderId);//订单号
        System.out.println("out_trade_no:" + orderId);
        int totalFeeDouble = (int) (Double.parseDouble(totalFee) * 100); // 假设 totalFee 是以元为单位的字符串,转化为分为单位的整数
        params.put("total_fee", String.valueOf(totalFeeDouble));
        System.out.println("total_fee:" + totalFeeDouble);
        params.put("spbill_create_ip", "123.123.123.123"); // 发起支付请求的ip，需要获取作为参数传入，这里是假设的
        System.out.println("spbill_create_ip:" + "123.123.123.123");
        params.put("notify_url", WeChatConfig.NOTIFY_URL);
        System.out.println("notify_url:" + WeChatConfig.NOTIFY_URL);
        params.put("trade_type", "JSAPI");
        System.out.println("trade_type:" + "JSAPI");
        params.put("openid", openid); // 添加 openid 参数
        System.out.println("openid:" + openid);

        // 生成签名
        String sign = WeChatPayUtil.generateSign(params);
        params.put("sign", sign);
        System.out.println("sign:" + sign);

        // 生成 XML
        String xml = mapToXML(params);
        System.out.println("xml:" + xml);

        // 发送请求
        String result = WeChatPayUtil.post("https://api.mch.weixin.qq.com/pay/unifiedorder", xml);
        System.out.println("result:" + result);

        if (result == null) {
            return Collections.singletonMap("return_code", "FAIL");
        }
        return WeChatPayUtil.parseXML(result);
    }

    // 返回支付信息给前端
    public Map<String, String> getPayParams(String prepayId) {
        System.out.println(222);
        Map<String, String> payParams = new HashMap<>();
        payParams.put("appId", WeChatConfig.APP_ID);
        System.out.println("appId:" + WeChatConfig.APP_ID);
        String timeStamp = String.valueOf(System.currentTimeMillis() / 1000);
        payParams.put("timeStamp", timeStamp);
        System.out.println("timeStamp:" + timeStamp);
        String nonceStr = WeChatPayUtil.generateNonceStr();
        payParams.put("nonceStr", nonceStr);
        System.out.println("nonceStr:" + nonceStr);
        payParams.put("package", "prepay_id=" + prepayId);
        System.out.println("package:" + "prepay_id=" + prepayId);
        payParams.put("signType", "MD5");
        System.out.println("signType:" + "MD5");

        // 生成支付签名
        String paySign = WeChatPayUtil.generateSign(payParams);
        payParams.put("paySign", paySign);
        System.out.println("paySign:" + paySign);
        return payParams;
    }

    // 处理支付结果通知
    public void handlePaymentNotification(HttpServletRequest request, HttpServletResponse response) throws IOException {
        try {
            String xml = getRequestBody(request);
            Map<String, String> result = WeChatPayUtil.parseXML(xml);
            if (WeChatPayUtil.validateSign(result)) {
                // 处理订单成功逻辑
                sendResponse(response, "<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>");
            } else {
                String returnMsg = result.get("return_msg");
                sendResponse(response, "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[" + returnMsg + "]]></return_msg></xml>");
            }
        } catch (Exception e) {
            sendResponse(response, "<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[处理支付结果通知异常]]></return_msg></xml>");
            throw new RuntimeException("处理支付结果通知异常", e);
        }
    }

    // 获取请求体
    private String getRequestBody(HttpServletRequest request) throws IOException {
        StringBuilder sb = new StringBuilder();
        BufferedReader reader = request.getReader();
        String line;
        while ((line = reader.readLine()) != null) {
            sb.append(line);
        }
        return sb.toString();
    }

    // 发送响应
    private void sendResponse(HttpServletResponse response, String result) throws IOException {
        response.setContentType("text/xml; charset=UTF-8");
        response.getWriter().write(result);
    }

    // Map转XML
    private String mapToXML(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        sb.append("<xml>");
        params.forEach((k, v) -> sb.append("<").append(k).append("><![CDATA[").append(v).append("]]></").append(k).append(">"));
        sb.append("</xml>");
        return sb.toString();
    }
}